package cn.cloud.jianghai.orderservice.service.impl;

import cn.cloud.jianghai.jianghaicommon.utils.ConvertUtil;
import cn.cloud.jianghai.orderapi.entity.OrderDto;
import cn.cloud.jianghai.orderservice.constant.RedisConstant;
import cn.cloud.jianghai.orderservice.domain.Order;
import cn.cloud.jianghai.orderservice.mapper.OrderMapper;
import cn.cloud.jianghai.orderservice.query.OrderQuery;
import cn.cloud.jianghai.orderservice.service.OrderService;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
* @author jianghai
* @description 针对表【t_order】的数据库操作Service实现
* @createDate 2022-05-22 11:52:29
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService{


    private final RedisTemplate<String, String> redisTemplate;

    @Override
    public List<OrderDto> findOrderList(OrderQuery orderQuery) {

        LambdaQueryWrapper<Order> lambdaQuery = getCondition(orderQuery);

        return ConvertUtil.copyListProperties(baseMapper.selectList(lambdaQuery), OrderDto.class);
    }

    /**
     * 构建查询参数
     * @param orderQuery 查询参数
     * @Date 2022/5/22 11:56
     * @Author Jiang.h
     * @return com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper<cn.cloud.jianghai.orderservice.domain.Order>
     **/
    private LambdaQueryWrapper<Order> getCondition(OrderQuery orderQuery) {

        LambdaQueryWrapper<Order> lambdaQuery = Wrappers.lambdaQuery();

        if (Objects.isNull(orderQuery)) {
            return lambdaQuery;
        }

        // 订单号过滤
        if (StringUtils.isNoneBlank(orderQuery.getNo())) {
            lambdaQuery.like(Order::getNo, orderQuery.getNo());
        }

        // 状态过滤
        if (Objects.nonNull(orderQuery.getStatus())) {
            lambdaQuery.eq(Order::getStatus, orderQuery.getStatus());
        }

        // 时间过滤
        if (Objects.nonNull(orderQuery.getStartTime()) && Objects.nonNull(orderQuery.getEndTime())) {
            lambdaQuery.between(Order::getGmtCreate, orderQuery.getStartTime(), orderQuery.getEndTime());
        }

        // 用户id过滤
        if (CollectionUtil.isNotEmpty(orderQuery.getUserIdList())) {
            lambdaQuery.in(Order::getUserId, orderQuery.getUserIdList());
        }

        return lambdaQuery;
    }

    @Override
    public Boolean insert(OrderDto orderDto) {

        return save(ConvertUtil.copyBeanProperties(orderDto, Order.class));
    }

    @Override
    public Boolean del(Long id) {

        return removeById(id);
    }

    @Override
    public Boolean edit(OrderDto orderDto) {

        return updateById(ConvertUtil.copyBeanProperties(orderDto, Order.class));
    }

    @Override
    public OrderDto get(Long id) {

        OrderDto orderDto;

        String redisData = redisTemplate.opsForValue().get(id.toString());

        if (StringUtils.isNoneBlank(redisData)) {

            log.info("查询订单缓存命中: {}", redisData);

            return JSON.parseObject(redisData, OrderDto.class);
        }

        Order order = this.getById(id);

        // 如果数据库不存在, 也插入redis当中, 只不过过期时间只有60秒. 如果存在的话则是一天过期时间
        boolean flag;
        long expireTime = (flag = Objects.nonNull(order)) ?  RedisConstant.EXPIRE_TIME : RedisConstant.EXPIRE_TIME_NULL;

        // 如果数据库不存在的话, 则往缓存中插入一个空对象
        orderDto = flag ? ConvertUtil.copyBeanProperties(order, OrderDto.class) : JSON.parseObject(RedisConstant.EMPTY_OBJECT, OrderDto.class);

        redisTemplate.opsForValue().set(id.toString(), JSON.toJSONString(order), expireTime, TimeUnit.MILLISECONDS);

        return orderDto;
    }

    @Override
    public Page<OrderDto> findByPage(OrderQuery query) {

        LambdaQueryWrapper<Order> lambdaQuery = getCondition(query);

        Page<Order> selectPage = baseMapper.selectPage(new Page<>(query.getPageNum(), query.getPageSize()), lambdaQuery);

        Page<OrderDto> resultPage = new Page<>(selectPage.getCurrent(), selectPage.getSize(), selectPage.getTotal());

        resultPage.setRecords(ConvertUtil.copyListProperties(selectPage.getRecords(), OrderDto.class));

        return resultPage;
    }
}




